# coding: utf-8
from typing import Union

from qfluentwidgets import InfoBar
from qfluentwidgets.multimedia import MediaPlayer
from qfluentwidgets.multimedia.video_widget import GraphicsVideoItem
from qtpy.QtCore import Signal, Qt, QEvent, QSizeF, QUrl
from qtpy.QtGui import QAction, QPainter, QKeyEvent
from qtpy.QtWidgets import QGraphicsView, QGraphicsScene

from .play_bar import MediaPlayBar


class VideoGraphicsView(QGraphicsView):
    downloadSignal = Signal(str, str)  # download MV
    fullScreenChanged = Signal(bool)  # enter/exit full screen

    def __init__(self, parent=None):
        super().__init__(parent)
        self.graphicsScene = QGraphicsScene(self)
        self.videoItem = GraphicsVideoItem()
        self.playBar = MediaPlayBar(self)
        self.player: MediaPlayer = self.playBar.player
        self.toggleFullScreenAct = QAction(self)
        self.__volume = 30
        self.__url = QUrl()

        self.__initWidgets()

    def __initWidgets(self):
        self.__setQss()
        self.setMouseTracking(True)
        self.setScene(self.graphicsScene)
        # 设置 Action
        self.toggleFullScreenAct.setShortcut(Qt.Key.Key_F11)
        self.toggleFullScreenAct.triggered.connect(self.__toggleFullScreen)
        self.addAction(self.toggleFullScreenAct)
        # 设置小部件播放视频
        self.graphicsScene.addItem(self.videoItem)
        self.player.setVideoOutput(self.videoItem)
        self.setRenderHints(
            QPainter.RenderHint.Antialiasing | QPainter.RenderHint.SmoothPixmapTransform | QPainter.RenderHint.LosslessImageRendering)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        # 初始化音量控制
        self.playBar.setVolume(self.__volume)
        self.playBar.installEventFilter(self)
        # 设置播放控制
        self.playBar.rotated.connect(lambda: self.rotate(45))
        self.playBar.fullScreenButton.clicked.connect(self.__toggleFullScreen)

        self.playBar.installEventFilter(self)

    def __toggleFullScreen(self):
        """ toggle full screen """
        isFull = not self.window().isFullScreen()
        self.playBar.fullScreenButton.setFullScreen(isFull)
        self.fullScreenChanged.emit(isFull)

    def togglePlayState(self):
        """ toggle play state """
        if self.player.isPlaying():
            self.pause()
            self.__infoBar('暂停')
        else:
            self.play()
            self.__infoBar('播放')

    def wheelEvent(self, e):
        """ 禁用滚动 """
        return

    def resizeEvent(self, e):
        super().resizeEvent(e)
        self.videoItem.setSize(QSizeF(self.size()))
        self.fitInView(self.videoItem, Qt.AspectRatioMode.KeepAspectRatio)
        self.playBar.move(11, self.height() - self.playBar.height() - 11)
        self.playBar.setFixedSize(self.width() - 22, self.playBar.height())

    def eventFilter(self, obj, e: QEvent):
        if obj is self.playBar:
            if e.type() == QEvent.Type.Hide:
                self.setCursor(Qt.CursorShape.BlankCursor)
            elif e.type() == QEvent.Type.Show:
                self.setCursor(Qt.CursorShape.ArrowCursor)

        return super().eventFilter(obj, e)

    def __setQss(self):
        """ 设置样式表 """
        self.setStyleSheet("""
            QGraphicsView {
                background: black;
                border: none
            }
        """)

    def rotate(self, angle: float):
        """ 旋转视频 """
        super().rotate(angle)
        self.fitInView(self.videoItem, Qt.AspectRatioMode.KeepAspectRatio)

    def play(self):
        """ 播放视频 """
        self.player.play()
        self.playBar.playButton.setPlay(True)

    def pause(self):
        """ 暂停视频 """
        self.player.pause()
        self.playBar.playButton.setPlay(False)

    def closeEvent(self, e):
        """ 关闭时暂停视频 """
        self.pause()
        e.accept()

    def mouseMoveEvent(self, e):
        self.playBar.show()
        self.playBar.timer.stop()
        self.playBar.timer.start(3000)

    def mousePressEvent(self, e):
        self.playBar.setVisible(not self.playBar.isVisible())

    def setSource(self, url: Union[QUrl, str]):
        """ 设置视频播放 """
        if isinstance(url, str):
            url = QUrl(url)
        self.__url = url
        self.player.setSource(url)
        self.fitInView(self.videoItem, Qt.AspectRatioMode.KeepAspectRatio)

    def setVolume(self, volume: int = None):
        """ 设置音量 """
        if volume is None:
            volume = self.__volume
        if volume < 0:
            self.__volume = 0
            return
        elif volume > 100:
            self.__volume = 100
            return
        self.__infoBar(f'音量：{volume}')
        self.__volume = volume
        self.playBar.setVolume(volume)

    def keyPressEvent(self, e: QKeyEvent):
        if e.key() == Qt.Key.Key_Left:
            self.playBar.skipBack(10000)
        elif e.key() == Qt.Key.Key_Right:
            self.playBar.skipForward(10000)
        elif e.key() == Qt.Key.Key_Up:
            self.__volume += 1
            self.setVolume()
        elif e.key() == Qt.Key.Key_Down:
            self.__volume -= 1
            self.setVolume()
        elif e.key() == Qt.Key.Key_Space:
            self.togglePlayState()
        elif e.key() == Qt.Key.Key_F11:
            self.__toggleFullScreen()
        elif e.key() == Qt.Key.Key_Escape:
            self.__toggleFullScreen()

        return super().keyPressEvent(e)

    def __infoBar(self, text: str, *, title: str = '', duration: int = 200):
        """ 显示提示信息 """
        InfoBar.info(title, text, isClosable=False, duration=duration, parent=self)
